// 错误处理
process.on('uncaughtException', (error) => {
    console.error('未捕获的异常:', error);
    process.exit(1);
});

process.on('unhandledRejection', (reason, promise) => {
    console.error('未处理的 Promise 拒绝:', reason);
    process.exit(1);
});

// 模块导入
const { customRequire, checkPluginDependencies } = require('./utils.js');
const { withRetry } = require('./playwrightUtils');
const { LoginPage } = require('./login_page.js');
const { FirstPage } = require('./first_page.js');
const { OrderListPage } = require('./order_list_page.js');
const { OrderDetailPage } = require('./order_detail_page.js');
const { sendLogToRenderer } = require('./sendLogToRenderer.js');
const { sendMonitoringData } = require('./user-data.js');
const manifest = require('./manifest.json');

// 依赖检查
const dependencies = ['playwright'];
checkPluginDependencies(dependencies);

// 动态导入依赖
const { chromium } = customRequire('playwright');

// 进度报告函数
function sendProgress(current, total, message) {
    const progress = {
        current,
        total,
        message,
        percentage: Math.round((current / total) * 100)
    };
    
    if (typeof process !== 'undefined' && process.send) {
        process.send({
            type: 'plugin-script-progress',
            data: progress
        });
    }
    
    console.log(`[PROGRESS] ${current}/${total} (${progress.percentage}%) - ${message}`);
}

// 数据接口定义（注释形式）
/*
interface cellDataRow {
    'Order No.': string;
    '是否单一分包实验室': string;
    'Assign Sample': string;
    'Quotation Save': string;
    'Quotation Generate': string;
    'Quotation Confirm': string;
    'Order Confirm': string;
    'Subcontract lab': string;
    'System contact name': string;
    'Subcontract Contact': string;
    'Expect due date': string;
    'Subcontract remark': string;
    'Subcontract Fee': string;
    'Accreditation Request': string;
    'SoftCopy Deliver To-others': string;
    'Return sample to-others': string;
    'Return Sample Way': string;
    'Report Requirement': string;
}
*/

/**
 * 打开浏览器并登录
 * @param {boolean} isPRD - 是否为生产环境
 * @param {boolean} headless - 是否为无头模式
 * @returns {Promise<Object>} - 返回浏览器和页面对象
 */
async function openBrowser(isPRD, headless) {
    // 发送日志
    const sendLog = (message, type = 'info') => {
        logger.info(message);
        console.log(`[${type}] ${message}`);
    };

    // 发送错误
    const sendError = (message) => {
        logger.error(message);
        console.error(`[error] ${message}`);
    };

    try {
        sendLog('正在启动浏览器...');
        
        // 根据是否为无头模式设置不同的启动参数
        const launchOptions = {
            headless: headless,
            executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
            args: headless ? [
                // 无头模式专用参数
                '--no-sandbox',
                '--disable-setuid-sandbox',
                '--disable-dev-shm-usage',
                '--disable-accelerated-2d-canvas',
                '--no-first-run',
                '--no-zygote',
                '--disable-gpu',
                '--disable-features=VizDisplayCompositor',
                '--disable-features=IsolateOrigins,site-per-process',
                '--window-size=1920,1080'
            ] : [
                // 有头模式参数
                '--start-maximized',
                '--disable-features=IsolateOrigins,site-per-process'
            ]
        };
        
        const browser = await chromium.launch(launchOptions);

        // 创建新页面，为无头模式设置合适的视口
        const contextOptions = headless ? 
            { viewport: { width: 1920, height: 1080 } } : 
            { viewport: null };
            
        const context = await browser.newContext(contextOptions);
        const page = await context.newPage();

        // 设置超时，无头模式使用更长的超时时间
        const timeout = headless ? 45000 : 30000;
        page.setDefaultTimeout(timeout);

        // 确定环境URL
        const baseUrl = isPRD 
            ? 'http://cnapp.sgs.net/gpo-web/#/' // 生产环境URL
            : 'http://cnapp-uat.sgs.net/sgsLogin/';     // UAT环境URL

        sendLog(`正在打开${isPRD ? 'PRD' : 'UAT'}环境: ${baseUrl}`);
        
        const login = new LoginPage(page);
        await login.GPOOpen(baseUrl);
        await login.singleSignOn();
        sendLog('浏览器初始化完成');
        return { browser, page, context };
    } catch (error) {
        sendError(`浏览器初始化失败: ${error.message}`);
        throw error;
    }
}

/**
 * 打开浏览器并登录
 * @param {boolean} isPRD - 是否为生产环境
 * @param {boolean} headless - 是否为无头模式
 * @returns {Promise<Object>} - 返回浏览器和页面对象
 */
async function openBrowser(isPRD, headless) {
    // 发送日志
    const sendLog = (message, type = 'info') => {
        sendLogToRenderer(message, type);
        console.log(`[${type}] ${message}`);
    };

    // 发送错误
    const sendError = (message) => {
        sendLogToRenderer(message, 'error');
        console.error(`[error] ${message}`);
    };

    try {
        sendLog('正在启动浏览器...');
        
        // 根据是否为无头模式设置不同的启动参数
        const launchOptions = {
            headless: headless,
            executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
            args: headless ? [
                // 无头模式专用参数
                '--no-sandbox',
                '--disable-setuid-sandbox',
                '--disable-dev-shm-usage',
                '--disable-accelerated-2d-canvas',
                '--no-first-run',
                '--no-zygote',
                '--disable-gpu',
                '--disable-features=VizDisplayCompositor',
                '--disable-features=IsolateOrigins,site-per-process',
                '--window-size=1920,1080'
            ] : [
                // 有头模式参数
                '--start-maximized',
                '--disable-features=IsolateOrigins,site-per-process'
            ]
        };
        
        const browser = await chromium.launch(launchOptions);

        // 创建新页面，为无头模式设置合适的视口
        const contextOptions = headless ? 
            { 
                viewport: { width: 1920, height: 1080 },
                userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
            } : 
            { 
                viewport: null,
                userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
            };
            
        const context = await browser.newContext(contextOptions);
        const page = await context.newPage();

        // 设置超时，无头模式使用更长的超时时间
        const timeout = headless ? 60000 : 45000;
        await context.setDefaultTimeout(timeout);
        await context.setDefaultNavigationTimeout(120000);

        // 确定环境URL
        const baseUrl = isPRD 
            ? 'http://cnapp.sgs.net/gpo-web/#/' // 生产环境URL
            : 'http://cnapp-uat.sgs.net/sgsLogin/';     // UAT环境URL

        sendLog(`正在打开${isPRD ? 'PRD' : 'UAT'}环境: ${baseUrl}`);
        
        const login = new LoginPage(page);
        try {
            await login.GPOOpen(baseUrl);
            await login.singleSignOn();
            sendLog('浏览器初始化完成');
        } catch (error) {
            // 网络连接错误处理
            if (error.message.includes('net::ERR_NAME_NOT_RESOLVED')) {
                sendError('网络连接失败：无法解析域名');
                sendError('建议解决方案：请连接SGS VPN后重试');
                throw new Error('网络连接失败：无法解析域名，请连接SGS VPN后重试');
            } else if (error.message.includes('net::ERR_INTERNET_DISCONNECTED')) {
                sendError('网络连接失败：网络已断开');
                sendError('建议解决方案：请检查网络连接后重试');
                throw new Error('网络连接失败：网络已断开，请检查网络连接后重试');
            } else if (error.message.includes('net::ERR_CONNECTION_TIMED_OUT')) {
                sendError('网络连接失败：连接超时');
                sendError('建议解决方案：请检查网络连接或稍后重试');
                throw new Error('网络连接失败：连接超时，请检查网络连接或稍后重试');
            } else {
                sendError(`登录页面打开失败: ${error.message}`);
                throw error;
            }
        }
        
        return { browser, page, context };
    } catch (error) {
        sendError(`浏览器初始化失败: ${error.message}`);
        throw error;
    }
}

/**
 * 主函数，接收从前端传递的参数
 * @param {Array} allCellData - 订单数据数组
 * @param {string} environment - 环境 ('PRD' 或 'UAT')
 * @param {boolean} isHeadless - 是否显示步骤（注意：这里需要取反作为headless参数）
 * @param {Object} userSettings - 用户设置
 * @returns {Promise<Object>} - 处理结果
 */
async function main(allCellData, environment = 'UAT', isHeadless = true, userSettings = {}) {
    try {
        // 根据环境判断是否为生产环境
        const isPRD = environment === 'PRD';
        // 注意：isHeadless在UI中表示是否显示步骤，而在这里需要取反
        const headless = !isHeadless;
        

        
        // 调用新建分包单函数
        const result = await newSubcontract(allCellData, isPRD, headless, userSettings);
        
        return result;
    } catch (error) {
        console.error('执行新建分包单时出错:', error);
        throw error;
    }
}

/**
 * 新建分包单业务函数
 * @param {Array} allCellData - 订单数据数组
 * @param {boolean} isPRD - 是否为生产环境
 * @param {boolean} headless - 是否为无头模式
 * @param {Object} userSettings - 用户设置
 * @returns {Promise<Object>} - 处理结果
 */
async function newSubcontract(allCellData, isPRD, headless, userSettings = {}) {
    let browser = null;
    let context = null;
    let page = null;
    let successCount = 0;
    let details = []; // 添加详细结果数组

    try {
        sendLogToRenderer('开始新建分包单流程', 'info');
        sendLogToRenderer(`环境: ${isPRD ? 'PRD' : 'UAT'}, 是否显示浏览器: ${headless}`, 'info');
        sendLogToRenderer(`待处理订单数量: ${allCellData.length}`, 'info');
        
        // 发送初始进度
        sendProgress(0, allCellData.length, '准备开始处理订单');

        // 打开浏览器
        const browserData = await openBrowser(isPRD, headless);
        browser = browserData.browser;
        page = browserData.page;
        context = browserData.context;

        // 导航到订单列表
        const firstPage = new FirstPage(page);
        await firstPage.orderListEntry();
        sendLogToRenderer('已进入订单列表页面', 'info');

        // 处理每个订单
        for (let i = 0; i < allCellData.length; i++) {
            const cellData = allCellData[i];
            let newPage = null;
            let isProcessingSuccessful = false;
            
            try {
                sendLogToRenderer(`开始处理订单: ${cellData['Order No.']} (${i + 1}/${allCellData.length})`, 'info');
                sendProgress(i, allCellData.length, `处理订单: ${cellData['Order No.']}`);

                // 搜索订单
                const orderListPage = new OrderListPage(page);
                await orderListPage.search_order_no(cellData['Order No.']);
                await orderListPage.click_first_order_no(cellData['Order No.'].toUpperCase());

                // 获取新打开的订单详情页
                const pages = context.pages();
                newPage = pages[pages.length - 1];
                const orderDetailPage = new OrderDetailPage(newPage);

                // Quotation 操作
                await withRetry(newPage, context, async () => {
                    await orderDetailPage.clickTabQuotation();
                }, `${cellData['Order No.']} 点击 Quotation tab`);

                if (cellData['Assign Sample'] === "yes") {
                    await orderDetailPage.quaPageClickAssignSample();
                }
                if (cellData['Quotation Save'] === "yes") {
                    await orderDetailPage.clickSave();
                }
                if (cellData['Quotation Generate'] === "yes") {
                    await orderDetailPage.clickGenerate();
                }
                if (cellData['Quotation Confirm'] === "yes") {
                    await orderDetailPage.clickConfirm();
                    const { selectApprove, warning } = await orderDetailPage.getWarningOrSelectApprove();
                    if (selectApprove && (await selectApprove.getAttribute('style')) != 'display: none;') {
                        await newPage.close();
                        sendLogToRenderer(`订单 ${cellData['Order No.']} 需要审批，跳过处理`, 'warning');
                        sendProgress(i + 1, allCellData.length, `跳过订单: ${cellData['Order No.']} (需要审批)`);
                        continue;
                    } else if (warning) {
                        const warningYesXpath = '//div[@aria-label="Warning"]/div/div[3]/button[2]';
                        await newPage.locator(warningYesXpath).click();
                    }
                }
                if (cellData['Order Confirm'] === "yes") {
                    await withRetry(newPage, context, async () => {
                        await orderDetailPage.clickConfirmOrder();
                    }, `${cellData['Order No.']} 点击 Confirm Order`);
                }

                // Subcontract 操作
                await withRetry(newPage, context, async () => {
                    await orderDetailPage.clickTabSubcontract();
                }, `${cellData['Order No.']} 点击 Subcontract tab`);

                await withRetry(newPage, context, async () => {
                    await orderDetailPage.subConPageClickNewSubcontract();
                }, `${cellData['Order No.']} 点击 New Subcontract`);

                // 填写分包信息
                await orderDetailPage.subConPageSubContractToQueryLabClick();
                await orderDetailPage.subConPageQueryLabInput(cellData['Subcontract lab'], cellData['System contact name']);
                await orderDetailPage.subConPageSubConContact(cellData['Subcontract Contact'] || '');
                await orderDetailPage.subConPageEditSubcontractSubConExpDueDate(cellData['Expect due date']);
                await orderDetailPage.subCon_page_editSubcontract_remark(cellData['Subcontract remark']);

                // 服务要求
                await orderDetailPage.subCon_page_editSubcontract_softCopyDeliveryTo(cellData['SoftCopy Deliver To-others']);
                await orderDetailPage.subCon_page_editSubcontract_accreditationRequest(cellData['Accreditation Request']);
                await orderDetailPage.subCon_page_editSubcontract_returnSampleTo(cellData['Return sample to-others']);
                await orderDetailPage.selectReturnSampleWay(cellData['Return Sample Way']);
                await orderDetailPage.subCon_page_editSubcontract_reportRequirement(cellData['Report Requirement']);

                // 测试项目选择
                if (cellData['是否单一分包实验室'] == "no") {
                    if (!cellData['Subcontract lab'].includes('SZ HL')) {
                        await orderDetailPage.subConPageEditSubcontractPageSearchBU(cellData['Subcontract lab']);
                        await orderDetailPage.subConPageEditSubcontractPageCheckboxAll();
                    } else {
                        await orderDetailPage.subConPageEditSubcontractPageCheckBUByRow(newPage);
                    }
                } else {
                    await orderDetailPage.subConPageEditSubcontractPageCheckboxAll();
                }

                await orderDetailPage.subCon_page_editSubcontract_subcontractFee(cellData['Subcontract Fee']);
                await orderDetailPage.subCon_page_editSubcontract_save();

                // 等待保存结果
                const selector = 'div.el-notification__content p';
                const element = await newPage.waitForSelector(selector);
                const content = await element.innerText();
                sendLogToRenderer(`${cellData['Order No.']} 新建分包单提示: ${content}`, 'info');

                await newPage.waitForTimeout(1500);

                // CCL 实验室特殊处理
                if (cellData['Subcontract lab'].includes('CCL')) {
                    const result = await orderDetailPage.subCon_page_cells_value(cellData['Order No.']);
                    sendLogToRenderer(`${cellData['Order No.']} 新建分包单结果: ${JSON.stringify(result)}`, 'info');
                    
                    if (result !== null) {
                        await newPage.waitForTimeout(2000);
                        const starLIMSIconXpath = result.starLIMSIcon_Xpath;
                        sendLogToRenderer(`starLIMSIconXpath: ${starLIMSIconXpath}`, 'info');
                        // await newPage.reload();

                        if (starLIMSIconXpath) {
                            await newPage.waitForTimeout(2000);
                            // 点击 starLIMS 图标
                            await withRetry(newPage, context, async () => {
                                await newPage.locator(starLIMSIconXpath).click({ force: true });
                            }, `${cellData['Order No.']} 点击 starLIMS 图标`);
                            
                            await context.setDefaultTimeout(60000);
                            await orderDetailPage.detailToStarLIMSConfirm();

                            // toStarLIMS提示
                            const element = await newPage.waitForSelector('div.el-notification__content p', { timeout: 5000 });
                            const content = await element.innerText();
                            sendLogToRenderer(`${cellData['Order No.']} toStarLims提示: ${content}`, 'info');
                        }
                    }
                }

                // 验证页面状态，确保处理过程中页面没有被关闭
                if (newPage.isClosed()) {
                    throw new Error('页面在处理过程中被关闭');
                }

                sendLogToRenderer(`订单处理完成：${cellData['Order No.']}`, 'info');
                successCount++;
                isProcessingSuccessful = true;
                sendProgress(i + 1, allCellData.length, `完成订单: ${cellData['Order No.']}`);

                // 发送监控数据
                const monitoringData = {
                    user_name: userSettings.email?.split('@')[0] || 'unknown',
                    user_location: userSettings.site || 'unknown',
                    rpa_id: "122",
                    rpa_name: "GPO_NewSubcontract",
                    rpa_version: manifest.version,
                    occurrence: new Date().toLocaleString('en-US', {
                        weekday: 'short',
                        day: '2-digit',
                        month: 'short',
                        year: 'numeric',
                        hour: '2-digit',
                        minute: '2-digit',
                        second: '2-digit',
                        hour12: false
                    }),
                    info: "GPO New Subcontract Order Processing.",
                    extra: cellData['Order No.']
                };
                
                let monitoringStatus = false;
                let monitoringMessage = '';
                try {
                    const monitoringResult = await sendMonitoringData([monitoringData]);
                    monitoringStatus = monitoringResult.success;
                    monitoringMessage = monitoringResult.message;
                    sendLogToRenderer(`监控数据发送${monitoringResult.success ? '成功' : '失败'}: ${monitoringResult.message}`, monitoringResult.success ? 'info' : 'warning');
                } catch (monitoringError) {
                    monitoringStatus = false;
                    monitoringMessage = `监控数据发送异常: ${monitoringError.message}`;
                    sendLogToRenderer(monitoringMessage, 'warning');
                }
                
                // 添加成功处理的详细结果
                details.push({
                    orderNo: cellData['Order No.'],
                    success: true,
                    message: '新建分包单成功',
                    monitoringStatus: monitoringStatus,
                    monitoringMessage: monitoringMessage
                });

                if (newPage && !newPage.isClosed()) {
                    await newPage.close();
                    await page.waitForTimeout(1000);
                }

            } catch (error) {
                sendLogToRenderer(`订单 ${cellData['Order No.']} 处理失败: ${error.message}`, 'error');
                sendProgress(i + 1, allCellData.length, `处理订单: ${cellData['Order No.']} 失败`);
                
                // 所有错误情况都标记为失败，包括页面被关闭的情况
                let errorMessage = error.message;
                if (error.message.includes('has been closed')) {
                    errorMessage = '处理过程中页面被意外关闭';
                }
                
                // 添加失败处理的详细结果
                details.push({
                    orderNo: cellData['Order No.'],
                    success: false,
                    message: `处理失败: ${errorMessage}`,
                    monitoringStatus: null,
                    monitoringMessage: '未发送监控数据（处理失败）'
                });
                continue;
            } finally {
                try {
                    if (newPage && !newPage.isClosed()) {
                        await newPage.close();
                        await page.waitForTimeout(1000);
                    }
                } catch (finallyError) {
                    sendLogToRenderer(`关闭页面时出错 ${cellData['Order No.']}: ${finallyError.message}`, 'error');
                }
            }
        }

        sendLogToRenderer(`新建分包单完成，成功处理 ${successCount} 个订单`, 'info');
        sendProgress(allCellData.length, allCellData.length, '所有订单处理完成');
        return { success: true, processedCount: successCount, totalCount: allCellData.length, details: details };

    } catch (error) {
        sendLogToRenderer(`新建分包单处理过程中发生错误，已成功处理 ${successCount} 个订单`, 'error');
        sendLogToRenderer(`错误详情：${error.message}`, 'error');
        return { success: false, processedCount: successCount, totalCount: allCellData.length, error: error.message, details: details };
    } finally {
        try {
            if (browser) {
                await browser.close();
                sendLogToRenderer('浏览器已关闭', 'info');
            }
        } catch (browserCloseError) {
            sendLogToRenderer(`关闭浏览器时出错: ${browserCloseError.message}`, 'error');
        }
    }
}

// 导出主函数 - 直接导出函数以供插件API调用
module.exports = main;

// 如果在主进程中直接运行，执行主函数
if (require.main === module) {
    // 命令行调用
    const args = process.argv.slice(2);
    if (args.length >= 3) {
        try {
            const allCellData = JSON.parse(args[0]);
            const environment = args[1] || 'UAT';
            const isHeadless = args[2] === 'true';
            const userSettings = args[3] ? JSON.parse(args[3]) : {};
            
            main(allCellData, environment, isHeadless, userSettings)
                .then(result => {
                    console.log('处理完成:', result);
                    process.exit(0);
                })
                .catch(error => {
                    console.error('处理失败:', error);
                    process.exit(1);
                });
        } catch (error) {
            console.error('参数解析失败:', error);
            process.exit(1);
        }
    } else {
        console.error('参数不足');
        process.exit(1);
    }
}